<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // async 函数
    // ES2017 标准引入了 async 函数，使得异步操作变得更加方便。

    // 如何创建async函数?  => 在function前加async关键词

    // 普通函数
    /* function fn() {
        console.log("函数fn执行了");
        return 100;
    }

    var result = fn();
    console.log("result", result); // 100 */

    // async函数  => 内部使用Promise对函数进行封装,返回Promise实例
    /*  async function fn() {
         console.log("函数fn执行了");


         // return 100; // 如果函数执行过程中没有出错, 会返回成功fulfilled状态的Promise实例, 返回值会作为Promise实例的数据存储
         aaaa; // 如果函数执行过程中出错, 会返回成功rejected状态的Promise实例, 错误对象会作为Promise实例的数据存储
     }

     var result = fn();
     console.log("result", result); // {<fulfilled>:100} */


    // async函数如何解决异步?  (前提: 异步操作还是需要用Promise封装)
    // async函数中存在await关键词, 等异步操作有结果(Promise实例状态改变)之后,再执行后续的代码,返回异步操作的结果()
    // 注意: await关键词应该在async函数/模块化语法中使用


    // 处理多个请求相互依赖的的情况  (等前面的异步操作执行完毕,再执行后续的代码)
    async function fn() {

        console.log("异步函数开始执行了");
        var p1 = await getNumAsync(1, 2000); // Promise实例(pending)  2s后变为{<fulfilled>:1}
        console.log(p1);

        // var p2 = await getNumAsync(2, 1000); // Promise实例(pending)  1s后变为{<fulfilled>:2}
        // console.log(p2);
        var p2 = await getNumAsync(2, 1000, false); // Promise实例(pending)  1s后变为{<rejected>:2} => async返回的Promsie实例会直接变为rejected,错误的信息也会存储到async返回的Promsie实例
        console.log(p2);


        var p3 = await getNumAsync(3, 3000); // Promise实例(pending)  3s后变为{<fulfilled>:3}
        console.log(p3);

        return p1 + p2 + p3;  //  // 如果函数执行过程中没有出错(等待上述所有异步全都执行完毕), 会返回成功fulfilled状态的Promise实例, 返回值会作为Promise实例的数据存储
    }

    // fn();// 执行异步函数,不接收结果 (成功就继续向后执行,失败没有catch捕获就直接抛出错误)

    var result = fn();   // 执行异步函数,接收结果 (成功就继续向后执行,失败就被catch捕获)
    console.log("result", result); // {<pedding>:undefined}

    result.then((res) => {
        console.log("全都成功", res);
    }).catch(res => {
        console.log("rejected", res);
    })

    function getNumAsync(num, delay = 0, isFulfilled = true) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                isFulfilled ? resolve(num) : reject(num);
            }, delay);
        })
    }

    console.log("同步代码全都执行完毕");
</script>

</html>